package org.ihelpuoo.weboo.module;

import java.util.Iterator;
import java.util.Map;

import org.ihelpuoo.io.FileUtils;
import org.ihelpuoo.orm.IIIException;
import org.ihelpuoo.orm.III;
import org.ihelpuoo.orm.ObjectManager;
import org.ihelpuoo.weboo.action.http.Action;
import org.ihelpuoo.weboo.bean.ActionBean;
import org.ihelpuoo.weboo.bean.ParamBean;
import org.ihelpuoo.weboo.bean.PropertyBean;
import org.ihelpuoo.weboo.exception.ActionConfigInvalidException;
import org.ihelpuoo.weboo.exception.ActionInstanceException;
import org.ihelpuoo.weboo.exception.ActionNotFoundException;
import org.ihelpuoo.weboo.exception.ModuleNotFoundException;
import org.ihelpuoo.weboo.util.ForwardTarget;

public class ActionManager extends ObjectManager
{
	private ModuleManager	moudleManager;
	private String			home;

	ActionManager(III factory, String home, ModuleManager moudleManager) throws IIIException
	{
		super(factory,FileUtils.findFile(home),".*.xml",ActionBean.class);
		this.moudleManager = moudleManager;
		this.home = home;
	}

	void mergeAllActionsWithParents() throws ActionNotFoundException, ModuleNotFoundException
	{
		if (null == this.objects)
			return;
		Iterator it = this.objects.values().iterator();
		while (it.hasNext())
		{
			ActionBean ab = (ActionBean)it.next();
			mergeAction(ab);
		}
	}

	private void mergeAction(ActionBean ab) throws ModuleNotFoundException, ActionNotFoundException
	{
		if (!ab.isMerged())
		{
			String pName = ab.getParent();
			if (null == pName)
			{
				ab.setMerged(true);
			}
			else
			{
				ForwardTarget parentName = new ForwardTarget(pName);

				Module m = moudleManager.getModule(parentName.getModuleName());
				ActionBean pa = m.getActionManager().getActionBean(parentName.getActionName());
				if (null == pa)
					throw new ActionNotFoundException(m.getName(),parentName.getActionName());
				mergeAction(pa);
				Map<String, ParamBean> pParams = pa.getParams();
				Map<String, ParamBean> params = ab.getParams();
				if (params == null)
				{
					ab.setParams(pParams);
				}
				else if (pParams != null)
				{
					Iterator<String> it = pParams.keySet().iterator();
					while (it.hasNext())
					{
						String key = it.next();
						if (!params.containsKey(key))
							params.put(key,pParams.get(key));
					}
				}
				Map<String, PropertyBean> pProperties = pa.getProperties();
				Map<String, PropertyBean> properties = ab.getProperties();
				if (properties == null)
				{
					ab.setProperties(pProperties);
				}
				else if (pProperties != null)
				{
					Iterator<String> it = pProperties.keySet().iterator();
					while (it.hasNext())
					{
						String key = it.next();
						if (!properties.containsKey(key))
							properties.put(key,pProperties.get(key));
					}
				}
				ab.setMerged(true);

			}
		}
	}

	String getHome()
	{
		return this.home;
	}

	public ActionBean getActionBean(String name)
	{
		return (ActionBean)getObject(name);
	}

	public ActionBean getActionBean(Class actionType)
	{
		return (ActionBean)getObject(actionType.getName());
	}

	public ActionConfig getActionConfig(String name) throws ActionConfigInvalidException
	{
		return ActionConfig.wrap(getActionBean(name),moudleManager);
	}

	public Action getAction(String name) throws ActionNotFoundException, ActionInstanceException
	{
		ActionBean ac = getActionBean(name);
		if (null == ac)
			throw new ActionNotFoundException(name);
		return ac.getAction();
	}

	public Iterator<String> iterator_action_name()
	{
		return objects.keySet().iterator();
	}

	public int size()
	{
		return objects.size();
	}
}
